<!DOCTYPE html>
<!--[if lt IE 7]>       <html class="no-js ie6 oldie" lang="en"> <![endif]-->
<!--[if IE 7]>          <html class="no-js ie7 oldie" lang="en"> <![endif]-->
<!--[if IE 8]>          <html class="no-js ie8 oldie" lang="en"> <![endif]-->
<!--[if gt IE 8]><!-->  <html class="no-js" lang="en"> <!--<![endif]-->
<head>
    <title>Introduction - CumulusTV</title>
    <meta name="description" content="Your Personal Cable Network" />
    <meta name="author" content="Nick Felker - Felker Tech">
    <meta charset="UTF-8">
    <link rel="icon" href="../themes/daux/img/favicon-blue.png" type="image/x-icon">
    <!-- Mobile -->
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!-- Font -->
    <link href='//fonts.googleapis.com/css?family=Roboto+Slab:400,100,300,700&subset=latin,cyrillic-ext,cyrillic' rel='stylesheet' type='text/css'>
    <!-- CSS -->
    <link href='../themes/daux/css/theme.min.css' rel='stylesheet' type='text/css'><link href='../themes/daux/css/theme-blue.min.css' rel='stylesheet' type='text/css'>
            <!-- Tipue Search -->
        <link href="../tipuesearch/tipuesearch.css" rel="stylesheet">
    
    <!--[if lt IE 9]>
    <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
</head>
<body class="">
    
    <a href="https://github.com/fleker/cumulustv" target="_blank" id="github-ribbon" class="github-ribbon hidden-print"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
<div class="container-fluid fluid-height wrapper">
    <div class="navbar navbar-static-top hidden-print">
        <div class="container-fluid">
            <a class="brand navbar-brand pull-left" href="../index.html">CumulusTV</a>

    <div class="navbar-right navbar-form search">
        <i class="glyphicon glyphicon-search search__icon">&nbsp;</i>
        <input type="search" id="tipue_search_input" class="form-control search__field" placeholder="Search..." autocomplete="on" results=25 autosave=text_search>
    </div>
        </div>
    </div>
    <div class="row columns content">
        <div class="left-column article-tree col-sm-3 hidden-print">
            <!-- For Mobile -->
            <div class="responsive-collapse">
                <button type="button" class="btn btn-sidebar" id="menu-spinner-button">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
            </div>
            <div id="sub-nav-collapse" class="sub-nav-collapse">
                <!-- Navigation -->
                <ul class='nav nav-list'><li class=''><a href="../Getting_Started.html">Getting Started</a></li><li class=' has-children'><a href="#" class="aj-nav folder"><i class="arrow">&nbsp;</i>Syncing</a><ul class='nav nav-list'><li class=''><a href="../Syncing/Setting_Up_Google_Drive.html">Setting Up Google Drive</a></li><li class=''><a href="../Syncing/Setting_Up_Live_Channels.html">Setting Up Live Channels</a></li><li class=''><a href="../Syncing/Importing_Streams.html">Importing Streams</a></li><li class=''><a href="../Syncing/Editing_JSON.html">Editing JSON</a></li></ul></li><li class=' has-children'><a href="#" class="aj-nav folder"><i class="arrow">&nbsp;</i>EPG</a><ul class='nav nav-list'><li class=''><a href="../EPG/Creating_a_Program_Guide.html">Creating a Program Guide</a></li><li class=''><a href="../EPG/XMLTV_Parser.html">XMLTV Parser</a></li></ul></li><li class=' has-children'><a href="#" class="aj-nav folder"><i class="arrow">&nbsp;</i>Features</a><ul class='nav nav-list'><li class=''><a href="../Features/Quick_Settings.html">Quick Settings</a></li><li class=''><a href="../Features/Exporting_M3u_Playlist.html">Exporting M3u Playlist</a></li></ul></li><li class=' has-children'><a href="#" class="aj-nav folder"><i class="arrow">&nbsp;</i>IPTV Channels</a><ul class='nav nav-list'><li class=''><a href="../IPTV_Channels/How_to_find_Channels.html">How to find Channels</a></li><li class=''><a href="../IPTV_Channels/Loading_Website.html">Loading Website</a></li><li class=''><a href="../IPTV_Channels/Radio.html">Radio</a></li><li class=''><a href="../IPTV_Channels/Parsing_M3U_Playlists.html">Parsing M3U Playlists</a></li><li class=''><a href="../IPTV_Channels/Linking_to_M3u_Playlist.html">Linking to M3u Playlist</a></li><li class=''><a href="../IPTV_Channels/Genres.html">Genres</a></li></ul></li><li class=''><a href="../Privacy_Policy.html">Privacy Policy</a></li><li class='open has-children'><a href="#" class="aj-nav folder"><i class="arrow">&nbsp;</i>Plugin API</a><ul class='nav nav-list'><li class='active'><a href="../Plugin_API/Introduction.html">Introduction</a></li><li class=''><a href="../Plugin_API/Release_Notes.html">Release Notes</a></li></ul></li><li class=' has-children'><a href="#" class="aj-nav folder"><i class="arrow">&nbsp;</i>Troubleshooting</a><ul class='nav nav-list'><li class=''><a href="../Troubleshooting/Common_Issues.html">Common Issues</a></li></ul></li></ul>

                <div class="sidebar-links">
                    
                        <!-- Links -->
                        <a href="http://reddit.com/r/cumulustv" target="_blank">Reddit Forum</a><br><a href="https://play.google.com/apps/testing/com.felkertech.n.cumulustv" target="_blank">Register for Beta</a><br><a href="https://play.google.com/store/apps/details?id=com.felkertech.n.cumulustv" target="_blank">Download on Google Play</a><br><a href="https://github.com/fleker/cumulustv" target="_blank">GitHub Repo</a><br><a href="https://github.com/googlesamples/androidtv-sample-inputs" target="_blank">TIF Companion Library</a><br>
                        <div id="toggleCodeBlock">
                                                    <a id="toggleCodeBlockBtn" href="#" onclick="toggleCodeBlocks();">Show Code Blocks Inline</a><br>
                                                </div>

                        <!-- Twitter -->
                                                    <div class="twitter">
                                <hr/>
                                <iframe allowtransparency="true" frameborder="0" scrolling="no" style="width:162px; height:20px;" src="https://platform.twitter.com/widgets/follow_button.html?screen_name=handnf&amp;show_count=false"></iframe>
                            </div>
                        
                        <hr/>
                    
                </div>
            </div>
        </div>
        <div class="right-column  content-area col-sm-9">

            <div class="content-page">
                                    <div id="tipue_search_content" style="display:none"></div>
                
                <div class="doc_content">
                    <article>
            <div class="page-header sub-header clearfix">
            <h1><a href="../Plugin_API/Introduction.html">Plugin API</a> <i class="glyphicon glyphicon-chevron-right"></i> <a href="../Plugin_API/Introduction.html">Introduction</a></h1>
            <span style="float: left; font-size: 10px; color: gray;">
                Tuesday, January 10, 2017            </span>
            <span style="float: right; font-size: 10px; color: gray;">
                4:45 PM            </span>
        </div>
    
    <p>There are many live streaming services, such as Periscope or Twitch, that have a complicated stream URL. They are difficult to memorize and expire after the stream is over, making it unreasonable for a user to add these streams to Live Channels. However, there are APIs which exist to obtain their source URL for a streaming user. To allow third-party developers to add functionality to Cumulus TV, there is a plugin system in place.</p>
<p>A plugin can be developed that will allow a third-party app to add, modify, or delete a channel through a simple API. It can also be called by CumulusTV when a channel is being tuned in order to actually obtain the stream URL.</p>
<p>Plugins that modify a channel will automatically add a <code>source</code> attribute to that channel with your package name. This is used by CumulusTV in order to select the right app when editing or playing.</p>
<p>The dialog activity that appears when you are adding or editing a chanel is actually a plugin itself.</p>
<h2 id="page_Requirements">Requirements</h2>
<ul>
<li>Android Studio - As plugins are just part of an Android app, you will need Android Studio downloaded and setup</li>
<li>Plugin library - In your project, add a line to add the CumulusTV plugin library, which is needed to generate plugins
<ul>
<li>Make sure you setup your gradle files to support <a href="https://jitpack.io/#Fleker/CumulusTV">JitPack</a>
</li>
<li>You can use the same release version as the application version.</li>
</ul>
</li>
<li>
<a href="https://play.google.com/store/apps/details?id=com.felkertech.n.cumulustv">CumulusTV</a> - You will need this app installed on your test device in order to properly interface with it. Keep in mind that your dependency version should be the same as the app version for ideal compatibility.</li>
</ul>
<p>Add to your gradle file:</p>
<pre><code>repositories {
    ...
    maven { url 'https://jitpack.io' }
}
</code></pre>
<p>And then add the dependency</p>
<pre><code>dependencies {
        compile 'com.github.Fleker:CumulusTV:1.7.+'
}
</code></pre>
<h2 id="page_Get_Started">Get Started</h2>
<p>Create a new activity (making sure it's added to your <code>AndroidManifest.xml</code>) and have it extend the <code>CumulusTvPlugin</code> class.</p>
<p><code>public class ListingPlugin extends CumulusTvPlugin</code></p>
<p>Your activity can have any UI and functionality that it wants to select channels and other types of data.</p>
<p>In <code>onCreate</code>, execute these two methods:</p>
<pre><code>    setLabel(&quot;&quot;);
    setProprietaryEditing(false);
    
</code></pre>
<p>If you set proprietary editing to true, only your app will be able to modify it in the future. It will set another parameter, <code>service</code>, to the value set by the label in <code>setLabel</code>.</p>
<h3 id="page_Identify_Intent">Identify Intent</h3>
<p>Your plugin may be activated by the user adding a new item, editing a current item, or reading items. You can use the methods:</p>
<ul>
<li>
<code>areEditing()</code>
</li>
<li>
<code>areAdding()</code>
</li>
<li>
<code>areReadingAll()</code>
</li>
</ul>
<p>Not every action needs to be supported, and if not, your plugin should exit the activity with <code>finish()</code> and provide a toast message saying the operation is unsupported. More API support for this may come in the future.</p>
<h3 id="page_Get_Item_to_Edit">Get Item to Edit</h3>
<p>If your plugin was activated to edit a currently existing item, you can obtain that by calling <code>getChannel()</code> to get a <code>CumulusChannel</code> or <code>getJson()</code> to get the raw JSON. You may prefer the raw JSON if you're using a custom type.</p>
<h4 id="page_Creating_Custom_Types">Creating Custom Types</h4>
<p>A custom type must have a <code>type</code> attribute in the JSON. This will prevent it from being edited by the app.</p>
<h4 id="page_Interface"><code>JsonContainer</code> Interface</h4>
<p>Custom types may benefit from having a separate class that implements <code>JsonContainer</code>. This will allow the app to parse that data and provides common methods that can be called on any item.</p>
<h3 id="page_Saving_Item">Saving Item</h3>
<p>You should create a new <code>CumulusChannel</code> using the <code>CumulusChannel.Builder</code> class or creating a new type that implements <code>JsonContainer</code>.</p>
<p>Then, your app should finish by calling <code>save(Object)</code>. This will save the data to the app and resync while also ending your activity. This should be the final action called, so any clean-up should be performed beforehand.</p>
<h2 id="page_Directly_Calling_Intents">Directly Calling Intents</h2>
<p>To open up one of these activities with a certain action, make sure to set the action to one of the options above. For example,</p>
<pre><code>Intent i = new Intent(getActivity(), ListingPlugin.class);
i.putExtra(CumulusTvPlugin.INTENT_EXTRA_ACTION, CumulusTvPlugin.INTENT_ADD);
startActivity(i);
</code></pre>
<h2 id="page_More_Info">More Info</h2>
<p>Want to see some examples? You can look at the <a href="https://github.com/Fleker/CumulusTV/blob/master/app/src/main/java/com/felkertech/cumulustv/plugins/MainPicker.java">MainPicker</a> and <a href="https://github.com/Fleker/CumulusTV/blob/master/app/src/main/java/com/felkertech/cumulustv/plugins/ListingPlugin.java">ListingPlugin</a> activities. Both use the same plugin interfaces that developers have access to.</p>

        <nav>
        <ul class="pager">
            <li><a href="../Privacy_Policy.html">Previous</a></li>            <li><a href="../Plugin_API/Release_Notes.html">Next</a></li>        </ul>
    </nav>
    </article>

                </div>
            </div>
        </div>
    </div>
</div>

    
    <!-- jQuery -->
    <script src="../themes/daux/js/jquery-1.11.3.min.js"></script>

    <!-- hightlight.js -->
    <script src="../themes/daux/js/highlight.pack.js"></script>
    <script>hljs.initHighlightingOnLoad();</script>

    <!-- JS -->
    
    <script src="../themes/daux/js/daux.js"></script>

            <!-- Tipue Search -->
        <script type="text/javascript" src="../tipuesearch/tipuesearch_set.js"></script>
        <script type="text/javascript" src="../tipuesearch/tipuesearch.min.js"></script>

        <script>
            window.onunload = function(){}; // force $(document).ready to be called on back/forward navigation in firefox
            $(document).ready(function() {
                $('#tipue_search_input').tipuesearch({
                    'show': 10,
                    'mode': 'json',
                    'base_url': '../'
                });
            });
        </script>
    
</body>
</html>
